#include "Core/Panels/MaterialsPanel.h"

#include <wx/colordlg.h>

#include <OgreSceneManager.h>
#include <OgreCamera.h>
#include <OgreLight.h>

#include <OgreScriptCompiler.h>
#include <OgreScriptTranslator.h>
#include <OgreScriptLexer.h>
#include <OgreScriptParser.h>
#include <OgreMaterialManager.h>


using namespace Ogre;

class MyScriptCompiler : public Ogre::ScriptCompiler
{
public:
	AbstractNodeListPtr generateAST(const String &str, const String &source, bool doImports, bool doObjects, bool doVariables)
	{
			return _generateAST(str, source, doImports, doObjects, doVariables);
	}

};

/*
class MyMaterialSerializer : public Ogre::MaterialSerializer
{
public:

	int serializeMaterialToString(Ogre::MaterialPtr mat, Ogre::String &out)
	{
		if(mat.isNull()) return 1;
		clearQueue();
		writeMaterial(mat);
		out = getQueuedAsString();
		clearQueue();
		return 0;
	}

};
*/

MaterialsPanel::MaterialsPanel( wxWindow* parent, Ogre::SceneManager *sceneManager, Ogre::Camera *camera ) :
		wxMaterialsPanel( parent ),
		m_sceneManager( sceneManager ),
		m_camera( camera )
{

}

int MaterialsPanel::selectMaterial(wxString name)
{

	//MyMaterialSerializer ms;

	Ogre::String matName = Ogre::String(name.mbc_str());

	Ogre::MaterialPtr mat = Ogre::MaterialManager::getSingleton().getByName(matName);
	if(mat.isNull()) return 1;

	String origin_filename = mat->getOrigin();

	String origin_group = "";
	try
	{
		origin_group = ResourceGroupManager::getSingleton().findGroupContainingResource(origin_filename);
	}
	catch (...)
	{
	}

	if(origin_group.empty())
	{
		txt->SetValue(wxT("unable to open material file: cannot find file: ") + wxString(origin_filename.c_str(), wxConvUTF8));
		return 1;
	}

	DataStreamPtr data = ResourceGroupManager::getSingleton().openResource(origin_filename, origin_group);
	if(data.isNull())
	{
		txt->SetValue(wxT("unable to open material file: cannot open file: ") + wxString(origin_filename.c_str(), wxConvUTF8));
		return 1;
	}

	// now the compiler part :)
	MyScriptCompiler sc;

	String content = data->getAsString();
	String source  = data->getName();

	sc.compile(content, source, origin_group);

	AbstractNodeListPtr nodes = sc.generateAST(content, source, true, true, true);
	AbstractNodeList *node_ptr = nodes.get();
	
	// Search for a top-level object node
rec:
	for(AbstractNodeList::iterator i = node_ptr->begin(); i != node_ptr->end(); ++i)
	{
		if((*i)->type == ANT_OBJECT)
		{
			ObjectAbstractNode *obj = (ObjectAbstractNode*)(*i).get();

			const map<String,String>::type vars = obj->getVariables();

			// Overlay the environment of one on top the other first
			for(map<String,String>::type::const_iterator iv = obj->getVariables().begin(); iv != obj->getVariables().end(); ++iv)
			{
				LogManager::getSingleton().logMessage(">> Material variable: " + iv->first + " = " + iv->second);
			}
			// Recurse into children
			node_ptr = &obj->children;
			goto rec;
		}
	}
	tree->DeleteAllItems();
	const wxTreeItemId rootId = tree->AddRoot( wxT("ROOT")  );

	/*
	const wxTreeItemId materialId	= tree->AppendItem( rootId, wxT("Materials") );
	const wxTreeItemId geomId		= tree->AppendItem( rootId, wxT("Geometry") );

	tree->AppendItem( geomId, wxT("EdgeList for Stencil shadows: ") +
		(m_meshEntity->getMesh()->isEdgeListBuilt() ?
		wxString(wxT("Yes")) : wxString(wxT("No")) ) );

	*/

	// old way: dump the material from memory:
	/*
	Ogre::String materialText;
	if(!ms.serializeMaterialToString(mat, materialText))
	{
		txt->SetValue(materialText.c_str());

	}
	*/
	return 0;
}
